package com.sunshuo.springsecuritydemo.access;

import com.sunshuo.springsecuritydemo.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @ClassName DynamicFilterInvocationSecurityMetadataSource
 * @Description 权限元数据
 * @Author sunshuo
 */
@Component
public class DynamicFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    private RoleService roleService;

    @Autowired
    public void setRoleService(RoleService roleService) {
        this.roleService = roleService;
    }

    @Override
    public Collection<ConfigAttribute> getAttributes(Object filterInvocationObject) throws IllegalArgumentException {
        // 获取请求
        HttpServletRequest request = ((FilterInvocation) filterInvocationObject).getRequest();
        // 加载请求资源权限信息
        Map<String, Set<String>> allResRoleNames = roleService.getAllResRoleNames();
        for (Map.Entry<String, Set<String>> entry : allResRoleNames.entrySet()) {
            String resUrl = entry.getKey();
            AntPathRequestMatcher matcher = new AntPathRequestMatcher(resUrl);
            if (matcher.matches(request)) {
                return SecurityConfig.createList(entry.getValue().toArray(new String[entry.getValue().size()]));
            }
        }
        // 该请求没有匹配资源，返回一个默认角色
        return Collections.EMPTY_LIST;
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return FilterInvocation.class.isAssignableFrom(aClass);
    }
}
